package com.vtquang.mymaps;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.database.Cursor;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.ProgressBar;

import com.vtquang.mymaps.adapter.DBAddressAdapter;
import com.vtquang.mymaps.adapter.SearchListAdapter;

public class SearchActivity extends Activity implements OnClickListener {
	public static final String ADDRESS_KEY = "address_key";
	public static final String LONGTITUE_KEY = "longtitue_key";
	public static final String LATITUE_KEY = "latituekey";

	private ImageButton btnClear;
	private ListView lvAddress;
	private EditText etSearch;
	private ProgressBar proBarSearch;

	private String _strSearch;
	private Thread thrSearch;

	private int _indexThread = 0;
	private DBAddressAdapter mDB;
	private boolean isDBOpen = false;

	private SearchListAdapter adapter; 
	private ArrayList<MyAddress> listAddress; 

	private Handler myHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			ObjecThread obj = (ObjecThread) msg.obj;
			switch (msg.what) {
			case 0:
				listAddress.clear();
				adapter.notifyDataSetChanged(); 
				break;
			case 1:
				if (obj.index == _indexThread) {
					listAddress.add(obj.address);
					adapter.notifyDataSetChanged(); 
				} else {
					listAddress.clear();
					adapter.notifyDataSetChanged(); 
				} 
				break;
			case 2:
				proBarSearch.setVisibility(View.INVISIBLE); 
			default:
				break;
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_search);

		btnClear = (ImageButton) findViewById(R.id.btnClear);
		lvAddress = (ListView) findViewById(R.id.lvAddress);
		etSearch = (EditText) findViewById(R.id.etSearch);
		proBarSearch = (ProgressBar) findViewById(R.id.proBar_Search);

		listAddress = new ArrayList<MyAddress>(); 
		adapter = new SearchListAdapter(getApplicationContext(), listAddress);
		lvAddress.setAdapter(adapter);
		
		mDB = new DBAddressAdapter(this);

		btnClear.setOnClickListener(this);
		etSearch.addTextChangedListener(new TextWatcher() {

			@Override
			public void afterTextChanged(Editable s) {
				_strSearch = s.toString();

				proBarSearch.setVisibility(View.VISIBLE);
				btnClear.setEnabled(_strSearch != "");

				if (_strSearch.length() > 0) {
					thrSearch = new Thread(new ThreadSearch(_indexThread));
				} else {
					thrSearch = new Thread(new ThreadGetDataBase());
				}
				thrSearch.start();
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				_indexThread++;
			}

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				proBarSearch.setVisibility(View.INVISIBLE);
			}
		});

		lvAddress.setOnItemClickListener(listener);

		thrSearch = new Thread(new ThreadGetDataBase());
		thrSearch.start();

		Dialog dialog = new Dialog(this);
		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		dialog.setContentView(R.layout.weatherdialog);
		dialog.setCancelable(false);  
	}
	
	@Override
	protected void onPause() {
		_indexThread++;
		super.onPause();
	}
 
	@Override
	protected void onStop() {
		if(isDBOpen){
			mDB.close();
		}
		super.onStop();
	}

	class ThreadSearch implements Runnable {
		private int index;

		public ThreadSearch(int a){
			index = a;
		}
		public ThreadSearch() {
			index = _indexThread;
		}

		@Override
		public void run() {
			Message msg = myHandler.obtainMessage(0, null);
			myHandler.sendMessage(msg);

			index = _indexThread;
			Geocoder geoCoder = new Geocoder(getApplicationContext(),
					Locale.getDefault());
			try {
				List<Address> addresses = geoCoder.getFromLocationName(
						_strSearch, 5);

				int count = addresses.size();
				if (count > 0) {
					for (int i = 0; i < count && (index == _indexThread); i++) {
						String name = "";
						String local = "";
						double lon = addresses.get(i).getLongitude();
						double lat = addresses.get(i).getLatitude();

						int maxline = addresses.get(i).getMaxAddressLineIndex();

						if (maxline >= 0)
							name += addresses.get(i).getAddressLine(0);

						for (int j = 1; j < maxline; j++) {
							local += addresses.get(i).getAddressLine(j);
							if (j < maxline - 1)
								local += ",";
							else
								local += ".";
						}

						MyAddress myaddress = new MyAddress(name, local, lon,
								lat);

						if (name.length() <= 0)
							name = addresses.get(i).getLocality();

						if (index == _indexThread) {
							ObjecThread obj = new ObjecThread();
							obj.index = index;
							obj.address = myaddress;

							msg = myHandler.obtainMessage(1, obj);
							myHandler.sendMessage(msg);
						}
					}
				}

				if (index == _indexThread) {
					msg = myHandler.obtainMessage(2, null);
					myHandler.sendMessage(msg);
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	class ThreadGetDataBase implements Runnable {
		private int index;

		public ThreadGetDataBase() {
			index = _indexThread;
		}

		@Override
		public void run() {
			Message msg = myHandler.obtainMessage(0, null);
			myHandler.sendMessage(msg);
			
			mDB.open();
			isDBOpen = true;

			Cursor mCursor = mDB.getAllAddress();
			int count = mCursor.getCount();
			if (count > 0) {
				mCursor.moveToLast();
				for (int i = count - 1; i >= 0 && (index == _indexThread); i--) {
					String name = mCursor.getString(1);
					String local = mCursor.getString(2);
					double lon = mCursor.getDouble(3);
					double lat = mCursor.getDouble(4);

					MyAddress myaddress = new MyAddress(name, local, lon, lat);

					if (index == _indexThread) {
						ObjecThread obj = new ObjecThread();
						obj.index = index;
						obj.address = myaddress;
						msg = myHandler.obtainMessage(1, obj);
						myHandler.sendMessage(msg);
					}

					if (!mCursor.moveToPrevious())
						break;
				}
			}

			if (index == _indexThread) {
				msg = myHandler.obtainMessage(2, null);
				myHandler.sendMessage(msg);
			}

			mCursor.close();
			mDB.close();
			isDBOpen = false;
		}

	}

	OnItemClickListener listener = new OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			MyAddress myaddress = listAddress.get(position);

			DBAddressAdapter db = new DBAddressAdapter(getApplicationContext());
			db.open();
			db.InsertAddress(myaddress);
			db.close();

			Intent intent = new Intent();
			// intent.putExtra(ADDRESS_KEY, myaddress.toString());
			intent.putExtra(LONGTITUE_KEY, myaddress.get_lon());
			intent.putExtra(LATITUE_KEY, myaddress.get_lat());
			setResult(RESULT_OK, intent);
			finish();
		}
	};

	@Override
	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.btnClear:
			_indexThread++;
			if (_strSearch != "") {
				etSearch.setText("");
				_strSearch = "";
			}
			break;

		default:
			break;
		}
	}

	public class ObjecThread {
		public int index;
		public MyAddress address;
	}
}
